Use case: Clock calibration (interrupt) ¶
The main differences between HAL1 and HAL2 in handling FDCAN clock calibration interrupts are as follows:
Activate notifications
In HAL1, calibration interrupts are enabled using
HAL_FDCAN_ActivateNotification()with interruptsFDCAN_IT_CALIB_STATE_CHANGEDandFDCAN_IT_CALIB_WATCHDOG_EVENT.In HAL2, these interrupts are enabled using
HAL_FDCAN_CCU_EnableInterrupts(). This is enough since the clock calibration has its own dedicated interrupts line.
Interrupt handler
In HAL1, all interrupts are handled by
HAL_FDCAN_IRQHandler().In HAL2, line 0 and line 1 interrupts are handled by
HAL_FDCAN_IRQHandler(), while clock calibration interrupts are handled byHAL_FDCAN_CCU_IRQHandler().
Calibration callback
In HAL1, the
HAL_FDCAN_ClockCalibrationCallback()is triggered with specific flags (FDCAN_IT_CALIB_STATE_CHANGEDorFDCAN_IT_CALIB_WATCHDOG_EVENT) to indicate calibration state changes or watchdog events.In HAL2, two callbacks are provided:
HAL_FDCAN_CCU_CalibrationCallback()to indicate calibration state changes.HAL_FDCAN_CCU_CalibrationWatchdogCallback()to indicate that the watchdog expired before calibration completed.
Sequence diagram ¶
Code snippet ¶
|
HAL1 |
HAL2 |
|---|---|
HAL_FDCAN_Start(&hfdcan);
CcuConfig.ClockCalibration = ENABLE;
CcuConfig.MinOscClkPeriods = 4;
CcuConfig.CalFieldLength = FDCAN_CALIB_FIELD_LENGTH_64;
CcuConfig.TimeQuantaPerBitTime = 20;
CcuConfig.WatchdogStartValue = 40;
HAL_FDCAN_ConfigClockCalibration(&hfdcan, &CcuConfig);
HAL_FDCAN_ConfigInterruptLines(&hfdcan,
FDCAN_IT_RX_BUFFER_NEW_MESSAGE
FDCAN_INTERRUPT_LINE0);
HAL_FDCAN_ActivateNotification(&hfdcan,
FDCAN_IT_RX_BUFFER_NEW_MESSAGE
| FDCAN_IT_CALIB_STATE_CHANGED
| FDCAN_IT_CALIB_WATCHDOG_EVENT,
FDCAN_TX_BUFFER0);
|
HAL_FDCAN_Start(&hfdcan);
hal_fdcan_ccu_clock_route_t clock_route = HAL_FDCAN_CCU_CLOCK_ROUTE_CALIBRATION;
HAL_FDCAN_CCU_SetClockRouting(&hfdcan, clock_route);
ccu_config.min_osc_clk_periods = 4;
ccu_config.calibration_field_length = HAL_FDCAN_CCU_FIELD_LENGTH_64;
ccu_config.time_quanta_per_bit_time = 20;
ccu_config.watchdog_start_value = 40;
HAL_FDCAN_CCU_SetConfigCalibrationUnit(&hfdcan, &ccu_config);
HAL_FDCAN_SetInterruptsToLine(&hfdcan,
HAL_FDCAN_IT_RX_BUFFER_NEW_MESSAGE
, HAL_FDCAN_IT_LINE_0);
HAL_FDCAN_EnableInterruptLines(&hfdcan, HAL_FDCAN_IT_LINE_0);
HAL_FDCAN_EnableInterrupts(&hfdcan,
HAL_FDCAN_IT_RX_BUFFER_NEW_MESSAGE
);
HAL_FDCAN_CCU_EnableInterrupts(&hfdcan,
HAL_FDCAN_CCU_IT_CALIBRATION_STATE_CHANGE
| HAL_FDCAN_CCU_IT_CALIBRATION_WATCHDOG_EVENT
);
|
Key changes ¶
HAL2 manages clock calibration interrupts through dedicated CCU APIs.
HAL2 introduces a dedicated IRQ handler for CCU interrupts.
![@startuml
participant App as "User Application"
participant "<font color=black><b>HAL FDCAN" as FDCAN #19DD3A
participant "NVIC" as NVIC#AliceBlue
participant "FDCAN Hardware System" as FDCAN_HW
== FDCAN Clock calibration Configuration ==
App -> FDCAN: HAL_FDCAN_ConfigClockCalibration(&hfdcan, &sCcuConfig)
FDCAN -> FDCAN_HW: Setup Clock Calibration Unit (CCU)
FDCAN_HW --> FDCAN: CCU configured
FDCAN --> App: <color green>HAL_OK
== Configure Reception Filters and enable interrupt ==
App -> FDCAN: HAL_FDCAN_ConfigFilter(&hfdcan, &sFilterConfig) [Calibration Filter]
note right
Configure at least one filter for both calibration frames to enter the
BASIC_CALIBRATED and the PRECISION_CALIBRATED
with IsCalibrationMsg = 1
endnote
FDCAN --> App: <color green>HAL_OK
App -> FDCAN: HAL_FDCAN_ConfigInterruptLines(&hfdcan, FDCAN_IT_RX_BUFFER_NEW_MESSAGE \n , FDCAN_INTERRUPT_LINE0)
FDCAN --> App: <color green>HAL_OK
App -> FDCAN: HAL_FDCAN_ActivateNotification(&hfdcan, FDCAN_IT_RX_BUFFER_NEW_MESSAGE \n | FDCAN_IT_CALIB_STATE_CHANGED \n | FDCAN_IT_CALIB_WATCHDOG_EVENT, FDCAN_TX_BUFFER0)
FDCAN --> App: <color green>HAL_OK
== FDCAN Clock calibration Process ==
App -> FDCAN: HAL_FDCAN_Start(&hfdcan)
FDCAN --> App: <color green>HAL_OK
hNote over FDCAN_HW: The FDCAN in <color red><b>Restricted Operation Mode</b></color>
hnote over FDCAN_HW
<font color=red><b>BASIC_CALIBRATION or NOT_CALIBRATED</b>
end note
FDCAN_HW <- : FDCAN Rx buffer new calibration message
note left
The configured filter <index> accept the calibration message
end note
FDCAN_HW --> NVIC: Rx Buffer New Message interrupt \n **FDCAN_IT0_IRQ**
NVIC -> FDCAN: HAL_FDCAN_IRQHandler()
FDCAN -> App: HAL_FDCAN_RxBufferNewMessageCallback()
FDCAN <-- App:
NVIC <-- FDCAN:
FDCAN_HW <-- NVIC:
alt watchdog counter reaches zero before state changed
FDCAN_HW --> FDCAN_HW: Watchdog counter reaches zero \n before CCU state changed
FDCAN_HW-->NVIC: CCU watchdog event \n **FDCAN_CCU_IRQ**
NVIC ->FDCAN: HAL_FDCAN_IRQHandler()
hnote over FDCAN_HW
<font color=red><b>NOT_CALIBRATED</b>
end note
FDCAN -> App: HAL_FDCAN_ClockCalibrationCallback(&hfdcan, FDCAN_IT_CALIB_WATCHDOG_EVENT)
hNote over App:<font color=red><b>failed
else state changed before watchdog counter reaches zero
FDCAN_HW --> FDCAN_HW: CCU state changed before\nWatchdog counter reaches zero
FDCAN_HW-->NVIC: CCU state change event \n **FDCAN_CCU_IRQ**
NVIC ->FDCAN: HAL_FDCAN_IRQHandler()
FDCAN -> App: HAL_FDCAN_ClockCalibrationCallback(&hfdcan, FDCAN_IT_CALIB_STATE_CHANGED)
App --> FDCAN:
FDCAN --> NVIC:
hnote over FDCAN_HW
<font color=orange><b>BASIC_CALIBRATION</b>
end note
end
'Precision Calibration Process'
FDCAN_HW <- : FDCAN **second** Rx buffer new message\n(From quartz node) starts with at least "1010"
note left
The configured filter <index> accept the calibration message
end note
FDCAN_HW --> NVIC: Rx Buffer New Message interrupt \n **FDCAN_IT0_IRQ**
NVIC -> FDCAN: HAL_FDCAN_IRQHandler()
FDCAN -> App: HAL_FDCAN_RxBufferNewMessageCallback()
FDCAN <-- App:
NVIC <-- FDCAN:
FDCAN_HW <-- NVIC:
alt watchdog counter reaches zero before state changed
FDCAN_HW --> FDCAN_HW: Watchdog counter reaches zero \n before CCU state changed
FDCAN_HW-->NVIC: CCU watchdog event \n **FDCAN_CCU_IRQ**
NVIC ->FDCAN: HAL_FDCAN_IRQHandler()
hnote over FDCAN_HW
<font color=red><b>NOT_CALIBRATED</b>
end note
FDCAN -> App: HAL_FDCAN_ClockCalibrationCallback(&hfdcan, FDCAN_IT_CALIB_WATCHDOG_EVENT)
hNote over App:<font color=red><b>failed
else state changed before watchdog counter reaches zero
FDCAN_HW --> FDCAN_HW: CCU state changed before\nWatchdog counter reaches zero
FDCAN_HW-->NVIC: CCU state change event \n **FDCAN_CCU_IRQ**
NVIC ->FDCAN: HAL_FDCAN_IRQHandler()
hnote over FDCAN_HW
<font color=green><b>PRECISION_CALIBRATED</b>
end note
FDCAN -> App: HAL_FDCAN_ClockCalibrationCallback(&hfdcan, FDCAN_IT_CALIB_STATE_CHANGED)
hNote over App:<font color=green><b>Success
App -> FDCAN: HAL_FDCAN_ExitRestrictedOperationMode
hNote over FDCAN_HW: The FDCAN in <color green><b>Normal Operation Mode</b></color>
App <-- FDCAN:<color green>HAL_OK
end
Note over App: The FDCAN is calibrated and ready to be used for communication.
@enduml](../../../../../_images/plantuml-4b54292113fd2e3735740d556ae58f6893474689.png)
